<template>
	<view>
		<view class="bottom-operation-box" @tap.stop="onBottom">
			<!-- <view class="flex_r line-break" v-if="keyboardHeight"> -->
			<view class="flex_r line-break" v-show="keyboardHeight">
				<view class="icon_ text_28 color__ line-break-box" @click="lineBreak">
					<view class="icon_ line-break-icon">
						<image
							class="img"
							src=""
							mode="aspectFill"
						></image>
					</view>
					换行
				</view>
			</view>
			<view class="flex_r bottom-operation">
				<!-- <view class="icon_ bottom-operation-icon" @click="onKeyboard">
					<image class="img" :src="isKeyboard ? a : a_b" mode="aspectFill"></image>
				</view> -->
				<view style="width: 10rpx"></view>
				<view class="flex_c_c flex1">
					<view class="bottom-operation-input" v-if="isKeyboard">
						<textarea
							class="input"
							auto-height="true"
							confirm-type="send"
							type="text"
							:focus="isFocus"
							:maxlength="-1"
							:adjust-position="false"
							v-model="text"
							confirm-hold
							:show-confirm-bar="false"
							@input="input"
							@confirm="sendingText"
							@focus="focus"
							@blur="isFocus = false"
							@keyboardheightchange="keyboardheightchange"
						/>
					</view>
					<!-- inputmode="none" -->
					<view class="icon_ text_32 bold_ bottom-operation-input" @touchend="touchend" @touchmove="touchmove" @touchstart="touchstart" v-else>
						<view>按住</view>
						<view style="width: 10rpx"></view>
						<view>说话</view>
					</view>

					<view class="icon_ text_26 quote" v-if="isQuote">
						<view class="flex1 quote-row">
							<view class="" v-if="quoteSource.type ===2">
								<m-image :value="quoteSource"></m-image>
							</view>
							<!-- <view class="" v-else-if="quoteSource.type === 'audio'">
								<m-audio :value="quoteSource"></m-audio>
							</view> -->
							<view class="" v-else-if="quoteSource.type === 1">
								<m-text :value="quoteSource"></m-text>
							</view>
							<view class="" v-else>
								<m-other :value="quoteSource"></m-other>
							</view>
						</view>
						<view class="quote-icon" @click="cancelQuote">
							<image
								class="img"
								src=""
								mode="aspectFill"
							></image>
						</view>
					</view>
				</view>
				<view style="width: 10rpx"></view>
				<view class="icon_ bottom-operation-icon" @click="tapEmoji">
					<image class="img" :src="b" mode="aspectFill"></image>
				</view>
				<view class="icon_ bottom-operation-icon" v-if="!text" @click="tapMore">
					<image class="img" :src="c" mode="aspectFill"></image>
				</view>
				<view class="send" v-if="text" @click.stop="sendingText">
					Send
				</view>
			</view>
			<view>
				<emoji v-model="isEmoji" @onEmoji="onEmoji" @deleteFn="deleteFn" @sendingText="sendingText" @sendingEmojiPack="sendingEmojiPack"></emoji>
			</view>
			<view>
				<more v-model="isMore" @onMore="onMore"></more>
			</view>
			<!-- 键盘高度 -->
			<view class="keyboard" :style="{ height: keyboardHeight + 'px' }"></view>
			<view v-if="keyboardHeight === 0">
				<m-bottom-paceholder></m-bottom-paceholder>
			</view>
			<!-- 语音输入 -->
			<m-recorder v-model="isRecorder" :isCancel="isCancel" @recorderTop="recorderTop" @touchend="touchend"></m-recorder>
		</view>
		<member-selection-loading title="选择提醒的人" ref="memberSelectionLoadingRef" :group_id="to.id" @itemclick="itemclick"></member-selection-loading>
	</view>
</template>

<script>
import { 自己的信息 } from '@/utils/test';

import { show, to as tofn, throttle, vibrateShortFn } from '@/utils/chat.js';
import emoji from './emoji.vue';
import more from './more.vue';
import mRecorder from './m-recorder.vue';
import memberSelectionLoading from '../memberSelectionLoading/index.vue';
import mText from '../item/quoteType/m-text.vue';
import mImage from '../item/quoteType/m-image.vue';
import mAudio from '../item/quoteType/m-audio.vue';
import mOther from '../item/quoteType/m-other.vue';
const recorderManager = uni.getRecorderManager();
import emConnect from '@/EaseIM/emApis/emConnect';
const { loginWithAccessToken, closeEaseIM } = emConnect();
//录音时长
let startTime = 0;
//
let inputValue = '';
let getSelectedTextRangeSetInterval = null;
let cursor = 0; //输入框光标

import { EMClient } from '@/EaseIM';
import { MESSAGE_TYPE } from '@/EaseIM/constant';
import { emMessages } from '@/EaseIM/emApis';
const { sendDisplayMessages } = emMessages();
const apiUrl = EMClient.apiUrl;
const orgName = EMClient.orgName;
const appName = EMClient.appName;
const uploadTargetUrl = `${apiUrl}/${orgName}/${appName}/chatfiles`;
const token = EMClient.token;
export default {
	components: {
		emoji,
		more,
		mRecorder,
		memberSelectionLoading,
		mText,
		mImage,
		mAudio,
		mOther
	},
	props: {
		to: {
			type: Object,
			default: {}
		},
		receiverid:{
			type:Number||String,
			default:0||''
		},
		userList: {
			type: Array,
			default: () => {
				return [];
			}
		},
		isPrivate: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
			a: '',
			a_b: '',
			b: '',
			c: '',
			isFocus: false, //键盘焦点
			isKeyboard: true,
			isEmoji: false,
			isMore: false,
			isRecorder: false,
			isCancel: false, //是否滑动到取消
			text: '',
			keyboardHeight: 0,
			isQuote: false, //是否引用
			quoteSource: {} //引用的源
		};
	},
	computed: {
	    user() {
	        return this.$store.state.user;
	    }
	},
	created() {
		this.initRecorderListeners();
		console.log('to////////////////',this.to)
		// 监听设置群公告
		uni.$off('getNoticeSendMessage', this.sendMessage);
		uni.$on('getNoticeSendMessage', this.sendMessage);

		// 监听修改群明
		uni.$off('getGroupNameMessage', this.sendMessage);
		uni.$on('getGroupNameMessage', this.sendMessage);
	},
	beforeDestroy() {
		uni.$off('getNoticeSendMessage', this.sendMessage);
		uni.$off('getGroupNameMessage', this.sendMessage);
		cursor = 0;
		clearInterval(getSelectedTextRangeSetInterval);
	},
	methods: {
		setCursor() {
			getSelectedTextRangeSetInterval = setInterval(() => {
				uni.getSelectedTextRange({
					success: (res) => {
						cursor = res.start;
					},
					fail: () => {
						clearInterval(getSelectedTextRangeSetInterval);
					}
				});
			}, 800);
		},
		// 滚动到底部
		backToBottom() {
			this.$emit('backToBottom');
		},
		// 关闭全部弹出/输入框/表情包
		closeAll() {
			this.isMore = false;
			this.isEmoji = false;
			this.isFocus = false;
		},

		onBottom() {
			this.$emit('onBottom');
		},
		// 重新编辑
		recalledEdit(item) {
			this.text = item.payload.text;
			this.$nextTick(() => {
				this.isFocus = true;
			});
		},
		// 关闭
		close() {
			this.isMore = false;
			this.isEmoji = false;
		},
		// 切换语音输入
		onKeyboard() {
			this.isKeyboard = !this.isKeyboard;
			this.isMore = false;
			this.isEmoji = false;
		},
		keyboardheightchange(e) {
			if (e.detail.duration > 0) {
				this.backToBottom();
			}
			// #ifdef APP || H5
			this.keyboardHeight = e.detail.height;
			this.isMore = false;
			this.isEmoji = false;
			// #endif

			// #ifdef MP
			if (e.detail.duration > 0) {
				throttle(() => {
					this.keyboardHeight = e.detail.height;
					this.isMore = false;
					this.isEmoji = false;
				}, 300);
			}
			// #endif
		},
		tapEmoji() {
			this.backToBottom();
			this.isEmoji = !this.isEmoji;
			if (this.isEmoji) {
				this.isKeyboard = true;
			}
			this.isMore = false;
			// #ifdef H5
			this.keyboardHeight = 0;
			// #endif
		},
		tapMore() {
			this.backToBottom();
			this.isMore = !this.isMore;
			this.isEmoji = false;
			// #ifdef H5
			this.keyboardHeight = 0;
			// #endif
		},
		onEmoji(key) {
			const text = `${this.text.slice(0, cursor)}${key}${this.text.slice(cursor)}`;
			this.text = text;
		},
		// ===========================
		// 获取焦点
		focus(e) {
			this.$emit('focus');
			this.isFocus = true;
			this.isEmoji = false;
			this.isMore = false;
			// #ifdef H5
			this.keyboardHeight = 300;
			this.backToBottom();
			// #endif
			clearInterval(getSelectedTextRangeSetInterval);
			this.setCursor();
		},
		// 监听输入
		input() {
			if (inputValue.length > this.text.length) {
			} else {
				const str = this.text.charAt(this.text.length - 1);
				if (str === '@') {
					if (this.isFocus === false) return;
					// this.$refs.memberSelectionLoadingRef.open();
					this.$nextTick(() => {
						this.isFocus = false;
					});
				}
			}
			inputValue = this.text;
		},
		// 插入换行符合
		lineBreak() {
			console.log('回车');
			console.log(cursor);
			const text = `${this.text.slice(0, cursor)}\n${this.text.slice(cursor)}`;
			this.text = text;
			// this.text = `${this.text}\r\n`;
			this.$nextTick(() => {
				this.isFocus = true;
			});
		},
		// 输入@某个成员
		itemclick(item) {
			if (item) {
				this.text = `${this.text}${item.name} `;
			}
			this.$nextTick(() => {
				this.isFocus = true;
			});
		},
		// 删除表情
		deleteFn() {
			const str = this.text.charAt(this.text.length - 1);
			if (str === ']') {
				let metaChars = /\[.*?(\u4e00*\u597d*)\]/g;
				let xstr = '';
				this.text.replace(metaChars, (match) => {
					xstr = match;
				});
				var text = this.text;
				function del(str) {
					return text.slice(0, text.length - str.length);
				}
				this.text = del(xstr);
			} else {
				this.text = this.text.substring(0, this.text.length - 1);
			}
		},
		// 引用
		quote(item) {
			// 删除嵌套引用
			const itemx = JSON.parse(JSON.stringify(item));
			itemx.payload['quoteSource'] = {};
			this.isQuote = true;
			this.quoteSource = itemx;
			console.log('haaaaaaaaaaaaaa',this.quoteSource)
			this.$nextTick(() => {
				this.isFocus = true;
			});
		},
		//谢谢红包
		thank(item) {
			this.text = '[彩带][玫瑰]谢谢红包！';
			this.sendingText();
		},
		//长按@某人
		mention(item) {
			this.text = `${this.text}@${item.sender_name} `;
			this.$nextTick(() => {
				setTimeout(() => {
					this.isFocus = true;
				}, 500);
			});
			try {
				vibrateShortFn();
			} catch (e) {
				//TODO handle the exception
			}
		},
		cancelQuote() {
			this.isQuote = false;
		},

		// 录音相关===============
		recorderTop(e) {
			this.recorderTopValue = e?.top;
		},
		initRecorderListeners() {
			// 监听录音开始
			recorderManager.onStart(() => {
				// console.log('开始录音');
				startTime = Date.now();
			});
			//录音结束后，发送
			recorderManager.onStop((res) => {
				this.isRecorder = false;
				if (this.isCancel) return console.log('取消发送'); //取消发送
				let endTime = Date.now();
				let duration = endTime - startTime;
				if (duration < 1000) return show('录音时间太短', 1000, 'error');
				res.duration = duration;
				// 创建信息
				this.sendingRecorder(res);
			});
			// 监听录音报错
			recorderManager.onError((res) => {
				this.isRecorder = false;
				recorderManager.stop();
				show('请检查麦克风权限');
			});
		},
		// 按下
		touchstart() {
			this.isRecorder = true;
			this.isCancel = false;
			try {
				recorderManager.start();
			} catch (e) {
				show('H5不支持');
			}
		},
		// 拖拽中
		touchmove(e) {
			let touch = e.touches[0]; //滑动过程中，手指滑动的坐标信息 返回的是Objcet对象
			if (touch.clientY <= this.recorderTopValue) {
				// 取消发送
				this.isCancel = true;
			} else {
				this.isCancel = false;
			}
		},
		// 松手
		touchend() {
			try {
				recorderManager.stop();
			} catch (e) {
				console.log('e:', e);
			}
			this.isRecorder = false;
		},
		// ===================
		// 更多操作相关===============
		onMore(item) {
			console.log(item)
			closeEaseIM();
			 console.log('store',this.$store.state.user)
			 let user = this.$store.state.user;
			 console.log('user////',user)
			 if(user.imuser){
              loginWithAccessToken(user.imuser, user.imtoken);
			 }
			
			switch (item.type) {
				// 拍摄
				case 'camera':
					this.openShot();
					break;
				case 'album':
					this.sendImageMessage();
					break;
				// case 'video':
				// 	this.sendVideoMessage();
				// 	break;
				// case 'red_envelope':
				// 	// 发红包
				// 	uni.$off('send_red_envelope', this.sendMessage);
				// 	uni.$on('send_red_envelope', this.sendMessage);

				// 	// 是否是单聊
				// 	if (this.isPrivate) {
				// 		tofn('/pagesGoEasy/envelope_sending/index-private', { ...this.to });
				// 	} else {
				// 		tofn('/pagesGoEasy/envelope_sending/index', { ...this.to });
				// 	}
				// 	break;
				// case 'mutualism':
				// 	// 蝌蚪互转
				// 	tofn('/pagesThree/tadpoleChange/index?type=1');
				// 	break;
				// case 'map':
				// 	// 位置
				// 	uni.chooseLocation({
				// 		success: async (res) => {
				// 			console.log(res);
				// 			uni.showLoading({
				// 				title: '发送中'
				// 			});
				// 			if (res2) {
				// 				this.createCustomMessageMap(res, 'http://xxxxxxxx/map/staticMap?location=116.459044,39.918732&size=300*170');
				// 			}
				// 			uni.hideLoading();
				// 		},
				// 		fail(e) {
				// 			console.log(e);
				// 		}
				// 	});
				// 	break;
				default:
					break;
			}
		},
		
		openShot() {
			let _this = this;
			uni.chooseImage({
			  count: 1,
			  sizeType: ['original', 'compressed'],
			  sourceType: [_this.$t('camera')],
			  success: (res) => {
			     _this.upLoadImage(res);
			  },
			  fail: (err) => {
			    uni.showToast({
			      title: err.errMsg,
			      icon: 'none',
			    });
			  },
			});
		},
		// =====================
		// 创建发送输入框内容
		sendingText() {
			if (!this.text)
				return uni.showModal({
					showCancel: false,
					content: '不能发送空白信息',
					success: function (res) {}
				});
			let body = this.text;
			if (this.text.length >= 50) {
				body = this.text.substring(0, 30) + '...';
			}
			if (this.isQuote) {
				this.createCustomMessageText(body);
				return;
			}

			this.sendMessage({
				text: this.text,
				type:1
			});

			this.text = '';
		},

		// 发送位置信息
		createCustomMessageMap(res, image) {
			const { latitude, longitude, address, name } = res;
			this.sendMessage({
				payload: {
					latitude,
					longitude,
					title: name,
					address,
					image //使用高德api生成图片
				},

				type: 'map'
			});
		},

		// 引用并发送文本
		createCustomMessageText(body) {
			this.sendMessage({
				text: this.text,
				type: 1
			});

			this.text = '';
		},

		// 创建发送照片内容
		sendImageMessage() {
			let _this = this;
			uni.chooseImage({
				count: 1,
				sizeType: ['original', 'compressed'],
				sourceType: ['album'],
				success: async (res) => {
					 _this.upLoadImage(res);
				}
			});
		},
		async upLoadImage(res) {
			let _this = this;
		  const tempFile = res?.tempFiles[0];
		  const tempFilePath =
		    (res && res.tempFilePaths && res.tempFilePaths[0]) ||
		    (res && res.tempFiles && res.tempFiles[0].tempFilePath);
		
		  console.log('tempFilePath', tempFilePath);
		  const imageName = tempFile?.name || 'image' + Date.now();
		  const imageType = tempFile?.type?.split('/')[1] || '';
		  let width = '';
		  let height = '';
		  uni.getImageInfo({
		    src: tempFilePath,
		    success: (res) => {
		      console.log('>>>>获取图片信息成功', res);
		      width = res.width;
		      height = res.height;
		    },
		    fail: (err) => {
		      console.log('>>>>>>获取图片信息失败', err);
		    },
		  });
		  uni.uploadFile({
		    url: uploadTargetUrl,
		    filePath: tempFilePath,
		    fileType: 'image',
		    name: 'file',
		    header: {
		      Authorization: 'Bearer ' + this.user.imtoken,
		    },
		    success: (res) => {
		      console.log('上传图片成功', res);
		      if (res.statusCode === 400) {
		        // 图片上传阿里云检验不合法
		        var errData = JSON.parse(res.data);
		        if (errData.error === 'content improper') {
		          uni.showToast({ title: '图片不合法', icon: 'none' });
		          return false;
		        }
		      }
		      this.sendImagesMessage(res, { imageName, width, height, imageType });
		      console.log(
		        '>>>>>>>执行发送图片信息',
		        imageName,
		        width,
		        height,
		        imageType
		      );
		      uni.showToast({ title: '图片已上传', icon: 'none' });
		    },
		    fail: (e) => {
		      console.log('>>>>>上传失败', e);
		      uni.showToast({ title: '图片上传失败', icon: 'none' });
		    },
		  });
		},
		async sendImagesMessage(res, { imageName, width, height, imageType }) {
		  console.log('>>>>>开始执行发送图片消息', res);
		
		  const dataObj = JSON.parse(res.data); // 接收消息对象
		  const params = {
		    type: MESSAGE_TYPE.IMAGE,
		    width: width,
		    height: height,
		    url: dataObj.uri + '/' + dataObj.entities[0].uuid,
		    // 消息接收方：单聊为对方用户 ID，群聊和聊天室分别为群组 ID 和聊天室 ID。
		    to: this.receiverid,
			imtoken:this.user.imtoken,
		    // 会话类型：单聊、群聊和聊天室分别为 `singleChat`、`groupChat` 和 `chatRoom`。
		    chatType: 'singleChat',
		    ext: {
		      imageName: imageName,
		      imageType: imageType,
		    },
		  };
		  try {
		    const res = await sendDisplayMessages({ ...params });
			console.log('图片上传返回结果123//////////////////////',res)
			this.sendMessage({
				url: res.message.url,
				filename:res.message.ext.imageName,
				width,
				height,
				type: 2
			});
		  } catch (error) {
			
		    if (error.type === 508) {
		      uni.showToast({
		        title: '发送内容不合规',
		        icon: 'none',
		      });
		    } else {
		      uni.showToast({
		        title: `消息发送失败${error.type}`,
		        icon: 'none',
		      });
		    }
		  } finally {
		    this.$emit('onCloseAllShowContainer', true);
		  }
		},
		// 创建发送照片内容
		createImageMessage(file) {
			this.sendMessage({
				url: file.path,
				type: 2
			});
		},
		// 创建发送视频内容
		sendVideoMessage() {
			uni.chooseVideo({
				success: async (res) => {
					console.log(res);
					this.createVideoMessage(res);
				}
			});
		},
		createVideoMessage(file) {
			this.sendMessage({
				payload: {
					video: {
						name: '3003009356267921_uni-video.mp4',
						url: file.tempFilePath,
						width: 640,
						height: 352,
						contentType: 'video/mp4',
						size: 501774,
						duration: 8.32
					},
					thumbnail: {
						name: 'uni-thumbnail.jpg',
						url: '封面路径',
						width: 364,
						height: 200,
						contentType: 'image/jpg'
					}
				},
				type: 'video'
			});
		},
		// 创建语音内容
		sendingRecorder(file) {
			this.sendMessage({
				payload: {
					contentType: 'audio/mp3',
					name: 'uni-audio.mp3',
					size: 2357,
					url: file.tempFilePath,
					duration: 1.148
				},
				type: 'audio'
			});
		},

		// 创建自定义表情包
		sendingEmojiPack(e) {
			console.log(e)
			this.sendMessage({
				payload: {
					ext: e.ext,
					url: e.url,
					path: e.path,
					text: e.text || '[表情包]'
				},
				content:e.text || '[表情包]',
				// type: 'emoji_pack'
				type:1,
			});
		},

		// 最终提交发送
		sendMessage(message) {
			console.log(message)
			this.$emit('send', message);
			this.isQuote = false;
			// this.quoteSource = {};
		}
	}
};
</script>

<style lang="scss" scoped>
.bottom-operation-box {
	position: relative;
	z-index: 9999;
	width: 100vw;
	background-color: #f6f6f6;
	.line-break {
		position: absolute;
		z-index: 99;
		left: 0;
		top: -58rpx;
		width: 100%;
		height: 60rpx;
		flex-direction: row-reverse;
		.line-break-box {
			position: relative;
			width: 160rpx;
			height: 100%;
			color: #2c2c2c;
			border-radius: 20rpx 0 0 0;
			background-color: #f6f6f6;
			.line-break-icon {
				width: 36rpx;
				height: 36rpx;
				margin-right: 10rpx;
			}
		}
		.line-break-box::before {
			position: absolute;
			left: -60rpx;
			top: 0;
			content: '';
			width: 60rpx;
			height: 60rpx;
			display: block;
			text-align: center;
			background-image: radial-gradient(240rpx at 2rpx 0px, rgba(168, 195, 59, 0) 60rpx, #f6f6f6 60rpx);
		}
	}
}
.bottom-operation {
	box-sizing: border-box;
	padding: 14rpx 10rpx;
	width: 100%;
	// align-items: flex-end;
	align-items: center;
	.bottom-operation-icon {
		width: 80rpx;
		height: 80rpx;
		.img {
			width: 80%;
			height: 80%;
		}
	}
	.send{
		background: seagreen;
		color: #ffffff;
		width: 98rpx;
		height: 56rpx;
		border-radius: 8rpx;
		font-size: 28rpx;
		line-height: 56rpx;
		// margin-top: -16rpx;
		text-align: center;
		
	}
	.bottom-operation-input {
		width: 100%;
		box-sizing: border-box;
		padding: 10rpx 14rpx;
		min-height: 84rpx;
		max-height: 300rpx;
		overflow: auto;
		border-radius: 10rpx;
		background-color: #fff;
		.input {
			width: 100%;
			margin: 10rpx 0;
		}
	}
}
.keyboard {
	transition: all 0.2s;
}

// 引用
.quote {
	box-sizing: border-box;
	padding: 0 20rpx;
	width: 100%;
	height: 50rpx;
	margin-top: 8rpx;
	border-radius: 10rpx;
	background-color: #eaeaea;
	color: #686868;
	.quote-row {
		width: 200rpx;
		text-overflow: ellipsis;
		overflow: auto;
		white-space: nowrap;
		::v-deep .quote-box {
			width: 100%;
			box-sizing: border-box;
			padding: 0;
			border-radius: 0;
			margin-top: 0;
			background-color: #eaeaea;
			color: #6b6b6b;
			.quote-name {
			}

			.m-image {
				border-radius: 6rpx;
				overflow: hidden;
				.img {
					width: 40rpx;
					height: 40rpx;
					border-radius: 6rpx;
					overflow: hidden;
					background-color: #fff;
				}
			}
		}
	}

	.quote-icon {
		width: 40rpx;
		height: 40rpx;
	}
}
</style>